<template>
  <el-dialog
    v-model="dialogVisible"
    :title="props.mode === 'dialog' ? '生成密码' : '密码生成器'"
    :width="props.mode === 'dialog' ? '700px' : '900px'"
    :close-on-click-modal="false"
  >
    <div class="generator-container">
      <!-- 生成的密码显示 -->
      <div class="password-display">
        <el-input
          v-model="generatedPassword"
          readonly
          size="large"
          :prefix-icon="Key"
        >
          <template #append>
            <el-button
              :icon="DocumentCopy"
              @click="copyPassword"
              title="复制密码"
            />
            <el-button
              :icon="Refresh"
              @click="generatePassword"
              title="重新生成"
            />
          </template>
        </el-input>
      </div>

      <!-- 密码强度显示 -->
      <div v-if="generatedPassword" class="password-strength">
        <div class="strength-bar">
          <div 
            class="strength-fill" 
            :class="strengthClass"
            :style="{ width: strengthWidth }"
          ></div>
        </div>
        <span class="strength-text" :class="strengthClass">
          强度：{{ strengthText }}
        </span>
      </div>

      <!-- 主要内容区域 - 左右布局 -->
      <div class="main-content">
        <!-- 左侧：生成选项 -->
        <div class="left-panel">
          <div class="options-section">
            <h4>生成选项</h4>
            
            <!-- 密码长度 -->
            <div class="option-item">
              <label>密码长度：</label>
              <div class="length-control">
                <el-slider
                  v-model="options.length"
                  :min="4"
                  :max="64"
                  show-input
                  :show-input-controls="false"
                  input-size="small"
                  style="width: 100%"
                />
              </div>
            </div>

            <!-- 字符类型选择 -->
            <div class="option-item">
              <label>包含字符：</label>
              <div class="character-options">
                <el-checkbox v-model="options.includeUppercase">
                  大写字母 (A-Z)
                </el-checkbox>
                <el-checkbox v-model="options.includeLowercase">
                  小写字母 (a-z)
                </el-checkbox>
                <el-checkbox v-model="options.includeNumbers">
                  数字 (0-9)
                </el-checkbox>
                <el-checkbox v-model="options.includeSymbols">
                  特殊符号 (!@#$...)
                </el-checkbox>
              </div>
            </div>

            <!-- 高级选项 -->
            <div class="option-item">
              <label>高级选项：</label>
              <div class="advanced-options">
                <el-checkbox v-model="options.excludeSimilar">
                  排除相似字符 (0,O,l,1,I)
                </el-checkbox>
                <el-checkbox v-model="options.excludeAmbiguous">
                  排除歧义字符 ({}[]()/\\'"~,;<>.\_)
                </el-checkbox>
                <el-checkbox v-model="options.includeSpace">
                  包含空格
                </el-checkbox>
              </div>
            </div>

            <!-- 自定义字符 -->
            <div class="option-item">
              <label>自定义字符：</label>
              <el-input
                v-model="options.customChars"
                placeholder="添加自定义字符"
                size="small"
              />
            </div>
          </div>
        </div>

        <!-- 右侧：密码历史 -->
        <div class="right-panel">
          <div class="password-list">
            <div class="list-header">
              <h4>生成历史</h4>
              <el-button size="small" @click="generateMultiple">
                批量生成
              </el-button>
            </div>
            
            <div class="password-items">
              <div
                v-for="(password, index) in passwordHistory"
                :key="index"
                class="password-item"
                @click="selectPassword(password)"
              >
                <span class="password-text">{{ password }}</span>
                <div class="password-actions">
                  <el-button
                    size="small"
                    :icon="DocumentCopy"
                    @click.stop="copyPasswordItem(password)"
                  />
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <template #footer>
      <div class="dialog-footer">
        <el-button @click="dialogVisible = false">
          {{ props.mode === 'dialog' ? '取消' : '关闭' }}
        </el-button>
        <el-button
          v-if="props.mode === 'dialog'"
          type="primary"
          @click="usePassword"
          :disabled="!generatedPassword"
        >
          使用此密码
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup>
import { ref, reactive, computed, watch, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import { Key, DocumentCopy, Refresh } from '@element-plus/icons-vue'

const props = defineProps({
  modelValue: {
    type: Boolean,
    default: false
  },
  mode: {
    type: String,
    default: 'standalone', // 'standalone' 或 'dialog'
    validator: (value) => ['standalone', 'dialog'].includes(value)
  }
})

const emit = defineEmits(['update:modelValue', 'generated'])

const dialogVisible = computed({
  get: () => props.modelValue,
  set: (value) => emit('update:modelValue', value)
})

const generatedPassword = ref('')
const passwordHistory = ref([])

// 生成选项
const options = reactive({
  length: 16,
  includeUppercase: true,
  includeLowercase: true,
  includeNumbers: true,
  includeSymbols: true,
  excludeSimilar: true,
  excludeAmbiguous: false,
  includeSpace: false,
  customChars: ''
})

// 字符集定义
const charSets = {
  uppercase: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
  lowercase: 'abcdefghijklmnopqrstuvwxyz',
  numbers: '0123456789',
  symbols: '!@#$%^&*()_+-=[]{}|;:,.<>?',
  similar: '0O1lI',
  ambiguous: '{}[]()/\\\'\"~,;<>._'
}

// 计算可用字符集
const availableChars = computed(() => {
  let chars = ''
  
  if (options.includeUppercase) chars += charSets.uppercase
  if (options.includeLowercase) chars += charSets.lowercase
  if (options.includeNumbers) chars += charSets.numbers
  if (options.includeSymbols) chars += charSets.symbols
  if (options.includeSpace) chars += ' '
  if (options.customChars) chars += options.customChars
  
  // 排除相似字符
  if (options.excludeSimilar) {
    chars = chars.replace(new RegExp(`[${charSets.similar}]`, 'g'), '')
  }
  
  // 排除歧义字符
  if (options.excludeAmbiguous) {
    chars = chars.replace(new RegExp(`[${charSets.ambiguous.replace(/[\[\]\\]/g, '\\$&')}]`, 'g'), '')
  }
  
  return chars
})

// 密码强度计算
const passwordStrength = computed(() => {
  const password = generatedPassword.value
  if (!password) return 0

  let score = 0
  
  // 长度评分
  if (password.length >= 8) score += 1
  if (password.length >= 12) score += 1
  if (password.length >= 16) score += 1
  
  // 字符类型评分
  if (/[a-z]/.test(password)) score += 1
  if (/[A-Z]/.test(password)) score += 1
  if (/[0-9]/.test(password)) score += 1
  if (/[^a-zA-Z0-9]/.test(password)) score += 1
  
  return Math.min(score, 6)
})

const strengthWidth = computed(() => `${(passwordStrength.value / 6) * 100}%`)

const strengthClass = computed(() => {
  const strength = passwordStrength.value
  if (strength <= 1) return 'weak'
  if (strength <= 2) return 'fair'
  if (strength <= 3) return 'good'
  if (strength <= 4) return 'strong'
  return 'very-strong'
})

const strengthText = computed(() => {
  const strength = passwordStrength.value
  if (strength <= 1) return '很弱'
  if (strength <= 2) return '较弱'
  if (strength <= 3) return '一般'
  if (strength <= 4) return '较强'
  if (strength <= 5) return '很强'
  return '极强'
})

// 生成密码
const generatePassword = () => {
  const chars = availableChars.value
  
  if (!chars) {
    ElMessage.warning('请至少选择一种字符类型')
    return
  }
  
  let password = ''
  
  // 确保至少包含每种选中的字符类型
  if (options.includeUppercase) {
    const upperChars = charSets.uppercase.split('').filter(char => chars.includes(char))
    if (upperChars.length > 0) {
      password += upperChars[Math.floor(Math.random() * upperChars.length)]
    }
  }
  
  if (options.includeLowercase) {
    const lowerChars = charSets.lowercase.split('').filter(char => chars.includes(char))
    if (lowerChars.length > 0) {
      password += lowerChars[Math.floor(Math.random() * lowerChars.length)]
    }
  }
  
  if (options.includeNumbers) {
    const numberChars = charSets.numbers.split('').filter(char => chars.includes(char))
    if (numberChars.length > 0) {
      password += numberChars[Math.floor(Math.random() * numberChars.length)]
    }
  }
  
  if (options.includeSymbols) {
    const symbolChars = charSets.symbols.split('').filter(char => chars.includes(char))
    if (symbolChars.length > 0) {
      password += symbolChars[Math.floor(Math.random() * symbolChars.length)]
    }
  }
  
  // 填充剩余长度
  for (let i = password.length; i < options.length; i++) {
    password += chars[Math.floor(Math.random() * chars.length)]
  }
  
  // 打乱密码字符顺序
  password = password.split('').sort(() => Math.random() - 0.5).join('')
  
  generatedPassword.value = password
  
  // 添加到历史记录
  if (!passwordHistory.value.includes(password)) {
    passwordHistory.value.unshift(password)
    // 限制历史记录数量
    if (passwordHistory.value.length > 10) {
      passwordHistory.value = passwordHistory.value.slice(0, 10)
    }
  }
}

// 批量生成密码
const generateMultiple = () => {
  const newPasswords = []
  for (let i = 0; i < 5; i++) {
    generatePassword()
    if (generatedPassword.value && !newPasswords.includes(generatedPassword.value)) {
      newPasswords.push(generatedPassword.value)
    }
  }
  ElMessage.success(`已生成 ${newPasswords.length} 个密码`)
}

// 复制密码
const copyPassword = async () => {
  try {
    await navigator.clipboard.writeText(generatedPassword.value)
    ElMessage.success('密码已复制到剪贴板')
  } catch (error) {
    // 备用方案
    const textArea = document.createElement('textarea')
    textArea.value = generatedPassword.value
    document.body.appendChild(textArea)
    textArea.select()
    document.execCommand('copy')
    document.body.removeChild(textArea)
    ElMessage.success('密码已复制到剪贴板')
  }
}

// 复制历史密码
const copyPasswordItem = async (password) => {
  try {
    await navigator.clipboard.writeText(password)
    ElMessage.success('密码已复制到剪贴板')
  } catch (error) {
    ElMessage.error('复制失败')
  }
}

// 选择密码
const selectPassword = (password) => {
  generatedPassword.value = password
}

// 使用密码
const usePassword = () => {
  if (generatedPassword.value) {
    emit('generated', generatedPassword.value)
  }
}

// 监听选项变化自动生成密码
watch(() => [
  options.length,
  options.includeUppercase,
  options.includeLowercase,
  options.includeNumbers,
  options.includeSymbols,
  options.excludeSimilar,
  options.excludeAmbiguous,
  options.includeSpace,
  options.customChars
], () => {
  if (availableChars.value) {
    generatePassword()
  }
}, { deep: true })

// 对话框打开时生成初始密码
watch(dialogVisible, (visible) => {
  if (visible && !generatedPassword.value) {
    generatePassword()
  }
})

onMounted(() => {
  if (dialogVisible.value) {
    generatePassword()
  }
})
</script>

<style scoped>
.generator-container {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.main-content {
  display: flex;
  gap: 24px;
  min-height: 400px;
}

.left-panel {
  flex: 1;
  min-width: 300px;
}

.right-panel {
  flex: 1;
  min-width: 300px;
}

.options-section {
  background: #f8f9fa;
  padding: 20px;
  border-radius: 8px;
  border: 1px solid #e9ecef;
  height: fit-content;
}

.password-list {
  background: #f8f9fa;
  padding: 20px;
  border-radius: 8px;
  border: 1px solid #e9ecef;
  height: 400px;
  display: flex;
  flex-direction: column;
}

.password-display .el-input {
  font-family: 'Courier New', monospace;
  font-size: 16px;
}

.password-strength {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 8px;
}

.strength-bar {
  flex: 1;
  height: 6px;
  background: #f0f0f0;
  border-radius: 3px;
  overflow: hidden;
}

.strength-fill {
  height: 100%;
  border-radius: 3px;
  transition: all 0.3s ease;
}

.strength-fill.weak {
  background: #f56c6c;
}

.strength-fill.fair {
  background: #e6a23c;
}

.strength-fill.good {
  background: #409eff;
}

.strength-fill.strong {
  background: #67c23a;
}

.strength-fill.very-strong {
  background: #13ce66;
}

.strength-text {
  font-size: 14px;
  font-weight: 500;
  min-width: 60px;
}

.strength-text.weak {
  color: #f56c6c;
}

.strength-text.fair {
  color: #e6a23c;
}

.strength-text.good {
  color: #409eff;
}

.strength-text.strong {
  color: #67c23a;
}

.strength-text.very-strong {
  color: #13ce66;
}

.options-section h4 {
  margin: 0 0 16px 0;
  color: #333;
  font-size: 16px;
}

.option-item {
  margin-bottom: 16px;
}

.option-item label {
  display: block;
  margin-bottom: 8px;
  font-weight: 500;
  color: #666;
}

.length-control {
  display: flex;
  align-items: center;
  gap: 16px;
}

.character-options,
.advanced-options {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}


.list-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
}

.list-header h4 {
  margin: 0;
  color: #333;
  font-size: 14px;
}

.password-items {
  flex: 1;
  overflow-y: auto;
  margin-top: 16px;
}

.password-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 12px;
  border: 1px solid #e6e6e6;
  border-radius: 4px;
  margin-bottom: 4px;
  cursor: pointer;
  transition: all 0.2s ease;
}

.password-item:hover {
  background: #f5f5f5;
  border-color: #409eff;
}

.password-text {
  font-family: 'Courier New', monospace;
  font-size: 14px;
  color: #333;
  word-break: break-all;
  flex: 1;
}

.password-actions {
  margin-left: 8px;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}
</style>
